package com.yun.zf.admin.controller;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import com.yun.zf.admin.service.*;
import com.yun.zf.common.admin.domain.SysUserPhone;
import com.yun.zf.common.admin.dto.HousePactMo;
import com.yun.zf.common.admin.dto.order.OrderSearchResMo;
import com.yun.zf.common.admin.dto.community.AgentInfoDto;
import com.yun.zf.common.admin.dto.customer.CustomerBasicInfo;
import com.yun.zf.common.admin.dto.pact.ComputeAmountDto;
import com.yun.zf.common.admin.dto.pact.OrderDto;
import com.yun.zf.common.admin.model.order.CreateOrderMo;
import com.yun.zf.common.admin.model.order.OrderMo;
import com.yun.zf.common.admin.model.order.SubOrderMo;
import com.yun.zf.common.admin.model.pact.OrderSearchMo;
import com.yun.zf.common.annotation.LogPrint;
import com.yun.zf.common.esRes.OrderIndexResMo;
import com.yun.zf.common.vo.Response;
import com.yun.zf.system.service.SysAgentService;
import com.yun.zf.system.service.SysUserPhoneService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 前端控制器
 * </p>
 *
 * @author cj
 * @since 2021-07-27
 */
@RestController
@RequestMapping("/order")
@Api(tags = "订单管理")
@Slf4j
public class OrderController extends BaseController {
    @Autowired
    private ZfHouseBasicService houseBasicService;
    @Autowired
    private ZfCustomerService customerService;
    @Autowired
    private ZfSubOrderService orderDetailService;
    @Autowired
    private SysAgentService agentService;
    @Autowired
    private ZfOrderService orderService;
    @Autowired
    private SysUserPhoneService phoneService;
    @Autowired
    private SysUserOrderService userOrderService;


    @PostMapping("/getHouseInfoToPact")
    @PreAuthorize("@ss.hasAnyRoles('agent')")
    @ApiOperation(value = "根据房源编号查询房源信息作为签约使用")
    @LogPrint(description = "创建订单查询房源信息")
    @DynamicParameters(name = "SendOrderMapModel", properties = {
            @DynamicParameter(name = "houseId", value = "房源编号", example = "111", required = true)
    })
    public Response<HousePactMo> getHouseInfoToPact(@RequestBody Map<String, String> map) {
        HousePactMo housePactMo = houseBasicService.searchHouseInfoToPact(map.get("houseId"), aCode, prov);
        if (housePactMo == null) {
            return Response.error("房源信息不存在");
        }
        return Response.success(housePactMo);
    }


    @PostMapping("/getCustomerInfo")
    @PreAuthorize("@ss.hasAnyRoles('agent')")
    @ApiOperation(value = "根据客源编号查询客源信息")
    @LogPrint(description = "创建订单查询客户信息")
    @DynamicParameters(name = "SendOrderMapModel", properties = {
            @DynamicParameter(name = "customerId", value = "客户编号", example = "111", required = true)
    })
    public Response getCustomerInfo(@RequestBody Map<String, String> map) {

        CustomerBasicInfo customer = customerService.getPactCustomer(prov, aCode, Long.parseLong(map.get("customerId")));
        if (customer == null) {
            return Response.error("客户信息不存在");
        }
        if (StringUtils.isBlank(customer.getCardNo())) {
            return Response.error("客户证件号码不能为空");
        }
        if (StringUtils.isBlank(customer.getBirthday())) {
            return Response.error("客户出生日期不能为空");
        }
        //1、 验证是否为注册用户
      /*  SysUserAuth auth = authService.getUserByIphone(Long.parseLong(customer.getIphone()));
        if (auth==null){
            return Response.error("客户非注册用户，请先进行注册");
        }*/
        return Response.success(customer);
    }


    @PostMapping("/computeAmount")
    @PreAuthorize("@ss.hasAnyRoles('agent')")
    @ApiOperation(value = "根据成交价计算订单金额")
    @ApiOperationSupport(order = 13)
    @LogPrint(description = "创建订单计算订单金额")
    @DynamicParameters(name = "SendOrderMapModel", properties = {
            @DynamicParameter(name = "finalPrice", value = "房源成交价", example = "111", required = true),
            @DynamicParameter(name = "type", value = "业务类型、租赁或者买卖", example = "1|2", required = true),
            @DynamicParameter(name = "communityId", value = "小区编号", example = "111")
    })
    public Response<ComputeAmountDto> computeAmount(@RequestBody Map<String, String> map) {
        if (StringUtils.isBlank(map.get("finalPrice")) || map.get("finalPrice").equals("0")) {
            return Response.error("请核实房源成交价");
        }

        Long communityId = 0L;
        if (StringUtils.isNotBlank(map.get("communityId"))) {
            communityId = Long.parseLong(map.get("communityId"));
        }
        List<SubOrderMo> details = orderDetailService.computeAmount(map.get("type"), new BigDecimal(map.get("finalPrice")), communityId, prov, aCode);
        if (details.size() == 0) {
            return Response.error("订单金额计算失败");
        }
        // 订单合计金额
        BigDecimal total = new BigDecimal("0");
        for (SubOrderMo detail : details) {
            total = total.add(detail.getAmount());
        }
        ComputeAmountDto amountDto = new ComputeAmountDto();
        amountDto.setTotal(total);
        amountDto.setDetails(details);
        return Response.success(amountDto);
    }

    @PostMapping("/getAgentInfo")
    @PreAuthorize("@ss.hasAnyRoles('agent')")
    @ApiOperation(value = "根据业务员工号获取业务员信息")
    @LogPrint(description = "创建订单查询业务员信息")
    @DynamicParameters(name = "OrderMapModel", properties = {
            @DynamicParameter(name = "agentNo", value = "业务员工号", example = "X000111", required = true)
    })
    public Response getAgentInfo(@RequestBody Map<String, String> map) {
        if (StringUtils.isBlank(map.get("agentNo"))) {
            return Response.error("业务员编号不能为空");
        }
        AgentInfoDto agent = agentService.getAgentByNo(Integer.parseInt(map.get("agentNo")), aCode);
        if (agent == null) {
            return Response.error("经纪人不存在");
        }
        return Response.success(agent);
    }

    @PostMapping("/createPact")
    @PreAuthorize("@ss.hasAnyRoles('agent')")
    @ApiOperation(value = "创建订单")
    @LogPrint(description = "创建订单")
    public Response createPact(@Validated @RequestBody OrderMo orderMo) {
        try {
            CreateOrderMo basicMo = orderMo.getBasicMo();
            Long communityId = 0L;
            if (StringUtils.isNotBlank(basicMo.getCommunityId())) {
                communityId = Long.parseLong(basicMo.getCommunityId());
            }

            //1、 验证订单分项金额是否一致
            List<SubOrderMo> details = orderDetailService.computeAmount(basicMo.getType(), basicMo.getFinalPrice(), communityId, prov, aCode);
            details = details.stream().sorted(Comparator.comparing(SubOrderMo::getMoneyType).reversed()).collect(Collectors.toList());
            List<SubOrderMo> ds = orderMo.getDetailMos();
            ds = ds.stream().sorted(Comparator.comparing(SubOrderMo::getMoneyType).reversed()).collect(Collectors.toList());
            // 这里比较需要对小数保留位数保持一致，在CustomerOrderDetailMo 对象中做了保留两位处理
            if (!CollectionUtils.isEqualCollection(details, ds)) {
                return Response.error("客户订单分项金额不一致，请确认");
            }
            // 2、 验证总订单金额是否一致
            // 订单合计金额
            BigDecimal total = new BigDecimal("0");
            for (SubOrderMo detail : details) {
                total = total.add(detail.getAmount());
            }
            if (total.compareTo(basicMo.getAmount()) != 0) {
                return Response.error("客户订单总金额不一致，请确认");
            }
            if (StringUtils.isBlank(orderMo.getId())) {
                Long orderId = orderService.creatOrder(orderMo, prov, aCode);
                Map<String, String> map = new HashMap<>();
                map.put("orderId", String.valueOf(orderId));
                return Response.success(map);
            } else {
                orderService.editOrder(orderMo, prov, aCode);
                return Response.success();
            }

        } catch (Exception e) {
            return Response.error("创建合同失败");
        }
    }

    @PostMapping("/getMyOrder")
    @PreAuthorize("@ss.hasAnyRoles('agent')")
    @ApiOperation(value = "全部订单")
    @LogPrint(description = "全部订单")
    public Response getMyOrder(@Validated @RequestBody OrderSearchMo searchMo) {
        Map<String, Object> map = orderService.orderSearch(searchMo, prov, aCode, agentNo);
        if (map == null) {
            return Response.error("未搜索到数据");
        }
        //2、 根据ID 查询列表信息
        List<OrderIndexResMo> sourceList = (List) map.get("records");
        List<Long> ids = new ArrayList<>();
        if (sourceList.size() <= 0) {
            return Response.error("未搜索到数据");
        }
        for (OrderIndexResMo hmap : sourceList) {
            ids.add(hmap.getOId());
        }
        Long proCode = sourceList.get(0).getProvinceCode();
        Long cityCode = sourceList.get(0).getCityCode();

        List<OrderSearchResMo> list = orderService.getOrderlist(proCode, cityCode, ids);
        map.put("records", list);
        // 获取符合条件的分页数据
        return Response.success(map);
    }

    @PostMapping("/myOrder")
    @PreAuthorize("@ss.hasAnyRoles('agent')")
    @ApiOperation(value = "我的订单")
    @LogPrint(description = "我的订单")
    public Response myOrder(@Validated @RequestBody OrderSearchMo searchMo) {
        if (agentNo == -1) {
            return Response.error("管理员用户不可查看我的订单");
        }
        // 我的订单只根据房源编号、客户编号和创建时间查询
        Page<OrderSearchResMo> searchResMos = orderService.getOrderRes(searchMo, prov, aCode, agentNo);
        if (searchResMos.getRecords().size() == 0) {
            return Response.error("未搜索到符合条件数据");
        }
        return Response.success(searchResMos);
    }

    @PostMapping("/orderDetail")
    @PreAuthorize("@ss.hasAnyRoles('agent')")
    @ApiOperation(value = "订单详情")
    @LogPrint(description = "订单详情")
    @DynamicParameters(name = "SendOrderMapModel", properties = {
            @DynamicParameter(name = "orderId", value = "订单号", example = "X000111", required = true)
    })
    public Response orderDetail(@RequestBody Map<String, String> map) {
        // 我的订单只根据房源编号、客户编号和创建时间查询
        OrderDto orderDetail = orderService.orderDetail(Long.parseLong(map.get("orderId")), prov, aCode);
        return Response.success(orderDetail);
    }

    @PostMapping("/sendOrder")
    @PreAuthorize("@ss.hasAnyRoles('agent')")
    @ApiOperation(value = "发送订单")
    @LogPrint(description = "发送订单")
    @DynamicParameters(name = "SendOrderMapModel", properties = {
            @DynamicParameter(name = "iphone", value = "客户手机号码", example = "X000111", required = true),
            @DynamicParameter(name = "subOrderId", value = "子订单号", example = "X000111", required = true),
            @DynamicParameter(name = "orderId", value = "订单号", example = "X000111", required = true)
    })
    public Response sendOrder(@RequestBody Map<String, String> map) {
        // 通过手机号码获取用户绑定id
        SysUserPhone phone = phoneService.getByIphone(Long.parseLong(map.get("iphone")));
        if (phone == null) {
            return Response.error("当前手机号码暂未绑定，请先至客户端进行绑定获取修改");
        }
        // 发送订单建立客户与订单直接的关系
        userOrderService.createUserOrder(phone.getUserId(), Long.parseLong(map.get("subOrderId")), prov, aCode, Long.parseLong(map.get("orderId")));
        return Response.success();
    }


    @PostMapping("/bringOrder")
    @PreAuthorize("@ss.hasAnyRoles('agent')")
    @ApiOperation(value = "订单编辑")
    @LogPrint(description = "订单编辑")
    @DynamicParameters(properties = {
            @DynamicParameter(name = "orderId", value = "订单号", example = "X000111", required = true)
    })
    public Response bringOrder(@RequestBody Map<String, String> map) {
        return Response.success(orderService.bringOrder(Long.parseLong(map.get("orderId")), prov, aCode));
    }


}

